using System;
using System.Activities;
using System.Activities.Presentation;
using System.Activities.Presentation.Services;
using System.Activities.Statements;
using System.Collections.Generic;
using System.IO;
using Microsoft.VisualBasic.Activities;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Headsight.BPMN2WF.Spielwiese
{
    [TestClass]
    public class SpielwieseTest
    {
        private static void VerifyOutcome(StringWriter writer, params String[] expected)
        {
            var splitted = writer.GetStringBuilder().ToString().Split(new[] { Environment.NewLine },
                                                                      StringSplitOptions.None);

            for (var i = 0; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], splitted[i]);
            }
        }

        [TestMethod]
        public void SimpleProgrammaticWorkflow()
        {
            var writer = new StringWriter();
            Console.SetOut(writer);

            var wf = new Sequence
            {
                Activities = 
                {
                    new WriteLine {Text = "Hello"},
                    new WriteLine {Text = "World"}
                }
            };

            WorkflowInvoker.Invoke(wf);

            VerifyOutcome(writer, "Hello", "World");
        }

        [TestMethod]
        public void TestHelloWorldVariables()
        {
            var writer = new StringWriter();
            Console.SetOut(writer);

            var wf = new Sequence
            {
                Variables = 
                {
                    new Variable<String> { Default = "Variable1Value", Name = "Variable1Name" },
                    new Variable<String> { Default = "Variable2Value", Name = "Variable2Name" } 
                },

                Activities = 
                {
                    new WriteLine { Text = new VisualBasicValue<String>("Variable1Name") },
                    new WriteLine { Text = new VisualBasicValue<String>("Variable2Name + \"_suffix\"") }
                }
            };

            WorkflowInvoker.Invoke(wf);

            VerifyOutcome(writer, "Variable1Value", "Variable2Value_suffix");
        }
        
        [TestMethod]
        public void HelloWorlfWF()
        {
            var writer = new StringWriter();
            Console.SetOut(writer);

            WorkflowInvoker.Invoke(new HelloWorldWF());
            
            VerifyOutcome(writer, "variable1Value", "variable2Value_suffix");
        }

        [TestMethod]
        public void WFWithArgument()
        {
            var argsIn = new Dictionary<String, Object>();
            argsIn["argument1"] = "argument1Value";

            var argsOut = WorkflowInvoker.Invoke(new WFWithArgument(), argsIn);

            var argument2 = argsOut["argument2"];
            Assert.AreEqual("argument1Value_argument1Value", argument2);
        }

        [TestMethod]
        public void CustomerActivityWF()
        {
            var argsIn = new Dictionary<String, Object>();
            argsIn["argIn"] = "value";

            var argsOut = WorkflowInvoker.Invoke(new CustomActivityWF(), argsIn);

            var argOut = argsOut["argOut"];
            Assert.AreEqual("valuevaluevaluevalue", argOut);
        }

        [TestMethod]
        public void WorkflowDesigner_Context()
        {
            var wfDesinger = new WorkflowDesigner();

            var editingContext = wfDesinger.Context;

            foreach (var each in editingContext.Items)
            {
                Console.WriteLine(each);
            }

            foreach (var each in editingContext.Services)
            {
                Console.WriteLine(each);
            }
        }

        [TestMethod]
        public void ProgrammaticCreationOfInArguments()
        {
            var workflowDesigner = new WorkflowDesigner();
            workflowDesigner.Load(new ActivityBuilder());

            var mSrv = workflowDesigner.Context.Services.GetService<ModelService>();

            var root = mSrv.Root;
            
            foreach (var each in root.Properties)
            {
                Console.WriteLine("{0} : {1}", each.Name, each.Value);
            }
        }

        [TestMethod]
        public void FlowSwitchTest()
        {
            WorkflowInvoker.Invoke(new FlowSwitchTest());
        }

    }
}